from merchant.apps.categories.models import Hierarchy, Category, Alias
from django.contrib import admin
from django import forms
#from ellington.core.forms import RequiredModelForm

#class CategoryAdminForm(RequiredModelForm):
class CategoryAdminForm(forms.ModelForm):
	'''
	required_if_other_not_given = {
		'hierarchy': 'parent',
		'parent': 'hierarchy',
	}
	'''
	class Meta:
		model = Category

	def clean_name(self):
		if '/' in self.cleaned_data['name']:
			raise forms.ValidationError, "A category name can't contain slashes."
		return self.cleaned_data['name']

	def clean(self):
		super(CategoryAdminForm, self).clean()
		
		if 'slug' in self.cleaned_data and 'parent' in self.cleaned_data and 'hierarchy' in self.cleaned_data:
			if self.cleaned_data['parent'] is not None:
				# inherit from parent
				self.cleaned_data['hierarchy'] = self.cleaned_data['parent'].hierarchy

			#Validate slug
			kwargs = {}
			if self.cleaned_data.get('hierarchy', False):
				kwargs['hierarchy__pk'] = int(self.cleaned_data['hierarchy'].id)
				kwargs['parent__isnull'] = True
			else:
				kwargs['parent__pk'] = int(self.cleaned_data['parent'].id)
			this_level_slugs = [c.slug for c in Category.objects.filter(**kwargs) if c.id != self.cleaned_data.get("id", None)]
			if self.cleaned_data['slug'] in this_level_slugs:
				raise forms.ValidationError("A category slug must be unique among categories at its level.")

			#Validate Category Parent
			"Makes sure the category doesn't set itself or any of its children as its parent."
			if not self.cleaned_data['parent']:
				return self.cleaned_data

			p_data = int(self.cleaned_data['parent'].pk)
			h_data = self.cleaned_data.get('hierarchy', False)
			if h_data:
				h_data = int(h_data.pk)
			if p_data and h_data:
				p = Category.objects.get(pk=p_data)
				if p.hierarchy_id != h_data:
					raise forms.ValidationError("This parent is not within the selected hierarchy.")

			# Check that the parent isn't a child of this category
			# Requires that we look up "this" object; if it doesn't exist
			# we can assume we're at the add stage and return
			this_id = self.cleaned_data.get("id", None)
			if not this_id:
				return self.cleaned_data

			try:
				selected_parent = Category.objects.get(pk=p_data)
			except Category.DoesNotExist:
				return self.cleaned_data

			if selected_parent.id == this_id:
				raise forms.ValidationError("A category can't be its own parent.")

			try:
				this_category = Category.objects.get(pk=p_data)
			except Category.DoesNotExist:
				return self.cleaned_data

			for c in this_category.get_all_children():
				if c.id == this_id:
					raise forms.ValidationError("A category can't set a child category to be its own parent.")
			return self.cleaned_data
		else:
			raise forms.ValidationError("Cannot clean data")


class CategoryAdmin(admin.ModelAdmin):
	form=CategoryAdminForm
	fields = ('hierarchy', 'parent', 'name', 'slug')
	list_display = ('__unicode__',)
	list_filter = ('hierarchy',)
	search_fields = ('name', 'path')
	prepopulated_fields = {'slug': ('name',)}


class HierarchyAdmin(admin.ModelAdmin):
	prepopulated_fields = {'slug': ('name',)}

class AliasAdmin(admin.ModelAdmin):
	list_display = ['category', 'parent']
	search_fields = ['category__name', 'parent__name']

admin.site.register(Category, CategoryAdmin)
admin.site.register(Hierarchy, HierarchyAdmin)
admin.site.register(Alias, AliasAdmin)
